package com.xuecheng.content.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xuecheng.api.content.model.CourseBaseDTO;
import com.xuecheng.api.content.model.qo.QueryCourseModel;
import com.xuecheng.common.domain.page.PageRequestParams;
import com.xuecheng.common.domain.page.PageVO;
import com.xuecheng.common.enums.common.CommonEnum;
import com.xuecheng.common.enums.content.CourseAuditEnum;
import com.xuecheng.common.util.StringUtil;
import com.xuecheng.content.convert.CourseBaseConvert;
import com.xuecheng.content.entity.CourseBase;
import com.xuecheng.content.entity.CourseMarket;
import com.xuecheng.content.mapper.CourseBaseMapper;
import com.xuecheng.content.service.CourseBaseService;
import com.xuecheng.content.service.CourseMarketService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.math.BigDecimal;
import java.util.Collections;
import java.util.List;

/**
 * <p>
 * 课程基本信息 服务实现类
 * </p>
 *
 * @author itcast
 */
@Slf4j
@Service
public class CourseBaseServiceImpl extends ServiceImpl<CourseBaseMapper, CourseBase> implements CourseBaseService {

    @Autowired
    CourseMarketService courseMarketService;

    /*
     *   1.是否需要开启事务
     *      由于是查询不许要开始事务
     *   2.判断关键的业务数据
     *     分页数据
     *     条件查询
     *   3.构建查询条件对象
     *   4.根据条件和分页数据进行查询操作
     *   5.封装查询数据
     * */
    @Override
    public PageVO queryCourseList(PageRequestParams params, QueryCourseModel model, long companyId) {
        Integer pageSize = params.getPageSize();
        Long pageNo = params.getPageNo();

        if (pageSize < 1) {
            pageSize = (PageRequestParams.DEFAULT_PAGE_SIZE);
        }
        if (pageNo < 1) {
            pageNo = (PageRequestParams.DEFAULT_PAGE_NUM);
        }

        //构建查询条件对象
        LambdaQueryWrapper<CourseBase> queryWrapper = new LambdaQueryWrapper<>();
        if (StringUtil.isNotBlank(model.getCourseName())) {
            queryWrapper.like(CourseBase::getName, model.getCourseName());
        }
        if (StringUtil.isNotBlank(model.getAuditStatus())) {
            queryWrapper.eq(CourseBase::getAuditStatus, model.getAuditStatus());
        }
        //添加数据是否有效的判断
        queryWrapper.eq(CourseBase::getStatus, CommonEnum.USING_FLAG.getCode());
        //添加对公司id的查询条件
        queryWrapper.eq(CourseBase::getCompanyId, companyId);
        //创建分页数据
        Page<CourseBase> page = new Page<>(pageNo, pageSize);

        //查询数据
        Page<CourseBase> pageResult = this.page(page, queryWrapper);

        List<CourseBase> records = pageResult.getRecords();
        long total = pageResult.getTotal();

        //CourseBase映射转换成CourseBaseDTO
        List<CourseBaseDTO> courseBaseDTOs = Collections.EMPTY_LIST;
        if (!ObjectUtils.isEmpty(records)) {
            courseBaseDTOs = CourseBaseConvert.INSTANCE.courseBaseToDTOs(records);
        }
        PageVO pageVO = new PageVO(courseBaseDTOs, total, pageNo, pageSize);
        return pageVO;
    }

    /**
     * 保存课程基本信息业务分析
     * 1、是否需要开启事务:增加必须添加事务
     * 2、对关键的数据的业务判断:课程基础信息中的关键数据
     * 3、保存的课程基础信息必须属于同一个用户id
     * 4、保存业务数据
     * 1、课程基础信息
     * 2、课程营销信息
     */
    @Override
    @Transactional
    public CourseBaseDTO createCourseBase(CourseBaseDTO baseDTO) {
        verifyCourseMsg(baseDTO);
        //2 保存业务数据
        //2.1 保存课程基本信息
        CourseBase courseBase = CourseBaseConvert.INSTANCE.courseBaseDtoToPo(baseDTO);
        courseBase.setId(null);
        courseBase.setAuditStatus(CourseAuditEnum.AUDIT_UNPAST_STATUS.getCode());
        boolean result = this.save(courseBase);
        if (!result) {
            throw new RuntimeException("保存课程基本信息失败");
        }

        //2.2 保存课程营销信息
        CourseMarket courseMarket = new CourseMarket();

        courseMarket.setCourseId(courseBase.getId());
        BigDecimal price = baseDTO.getPrice();
        courseMarket.setPrice(price.floatValue());
        courseMarket.setCharge(baseDTO.getCharge());

        boolean save = courseMarketService.save(courseMarket);
        if (!save) {
            throw new RuntimeException("保存课程营销数据失败");
        }

        CourseBase po = this.getById(courseBase.getId());
        return CourseBaseConvert.INSTANCE.courseBaseToDTO(po);
    }

    /**
     * 校验课程基础信息
     * @param baseDTO 课程信息传输类
     */
    private void verifyCourseMsg(CourseBaseDTO baseDTO) {
        //1 判断关键数据
        if (StringUtil.isBlank(baseDTO.getName())) {
            throw new RuntimeException("课程名称不能为空");
        }
        if (StringUtil.isBlank(baseDTO.getMt())) {
            throw new RuntimeException("课程大分类不能为空");
        }
        if (StringUtil.isBlank(baseDTO.getSt())) {
            throw new RuntimeException("课程小分类不能为空");
        }
        if (StringUtil.isBlank(baseDTO.getGrade())) {
            throw new RuntimeException("课程等级不能为空");
        }
        if (ObjectUtils.isEmpty(baseDTO.getCompanyId())) {
            throw new RuntimeException("机构id不能为空");
        }
        if (StringUtil.isBlank(baseDTO.getTeachmode())) {
            throw new RuntimeException("课程模式不能为空");
        }
    }

    @Override
    public CourseBaseDTO getByCourseId(Long courseId, Long companyId) {
        if (ObjectUtils.isEmpty(courseId) || ObjectUtils.isEmpty(courseId)) {
            throw new RuntimeException("非法数据");
        }
        //1.获取课程基本信息
        CourseBase courseBase = this.getById(courseId);

        CourseBaseDTO courseBaseDTO = null;
        //2.封装CourseBaseDTO
        if (ObjectUtils.isEmpty(courseBase)) {
            courseBaseDTO = new CourseBaseDTO();
        } else {
            //判断是否为同一机构
            if (!ObjectUtils.nullSafeEquals(courseBase.getCompanyId(), companyId)) {
                throw new RuntimeException("无权限访问");
            } else {
                courseBaseDTO = CourseBaseConvert.INSTANCE.courseBaseToDTO(courseBase);
                //封装课程营销数据到CourseBaseDTO
                LambdaQueryWrapper<CourseMarket> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(CourseMarket::getCourseId, courseId);

                CourseMarket courseMarket = this.courseMarketService.getOne(queryWrapper);
                courseBaseDTO.setPrice(BigDecimal.valueOf(courseMarket.getPrice()));
                courseBaseDTO.setCharge(courseMarket.getCharge());
            }
        }
        return courseBaseDTO;
    }

    @Override
    @Transactional
    public CourseBaseDTO modifyCourseBase(CourseBaseDTO courseBaseDTO) {
        verifyCourseMsg(courseBaseDTO);

        if (ObjectUtils.isEmpty(courseBaseDTO.getCourseBaseId())) {
            throw new RuntimeException("课程信息id不能为空");
        }
        //查询课程基本信息
        CourseBase courseBase = getById(courseBaseDTO.getCourseBaseId());

        if (ObjectUtils.isEmpty(courseBase)) {
            throw new RuntimeException("查询不到要修改的课程信息");
        }

        if (!ObjectUtils.nullSafeEquals(courseBase.getCompanyId(), courseBaseDTO.getCompanyId())) {
            throw new RuntimeException("无权限修改数据");
        }
        //确定审核状态
        String auditStatus = courseBaseDTO.getAuditStatus();
        if (CourseAuditEnum.AUDIT_COMMIT_STATUS.getCode().equals(auditStatus) ||
                CourseAuditEnum.AUDIT_PASTED_STATUS.getCode().equals(auditStatus) ||
                CourseAuditEnum.AUDIT_PUBLISHED_STATUS.getCode().equals(auditStatus)) {
            throw new RuntimeException("课程已提交或正在审核");
        }
        //修改course_base
        courseBase = CourseBaseConvert.INSTANCE.courseBaseDtoToPo(courseBaseDTO);
        boolean result = updateById(courseBase);
        if (!result) {
            throw new RuntimeException("修改数据失败");
        }

        //修改course_market
        LambdaUpdateWrapper<CourseMarket> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(CourseMarket::getCourseId, courseBase.getId());
        updateWrapper.set(CourseMarket::getCharge, courseBaseDTO.getCharge());
        updateWrapper.set(CourseMarket::getPrice,
                courseBaseDTO.getPrice() == null ? 0 : courseBaseDTO.getPrice().floatValue());
        boolean update = this.courseMarketService.update(updateWrapper);
        if (!update) {
            throw new RuntimeException("修改课程营销数据失败");
        }

        return courseBaseDTO;
    }
}
